#include "detectorwidget.h"
#include "ui_detectorwidget.h"
#include "gigedeviceobject.h"
#include "../../ImageAcquisitor/global.h"

#include <QThread>
#include <QFile>
#include <QSettings>
#include <QJsonObject>

DetectorWidget::DetectorWidget(QWidget *parent) :
    d(new GigEDeviceObject),
    t(new QThread(this)),
    m_proc(0),
    m_userData(0),
    QWidget(parent),
    ui(new Ui::DetectorWidget)
{
    ui->setupUi(this);
    init();
}

DetectorWidget::~DetectorWidget()
{
    t->quit();
    t->wait(3000);
    delete ui;
}

void DetectorWidget::init()
{
    connect(ui->acqBtn, SIGNAL(toggled(bool)), d, SLOT(startCapture(bool)));
    connect(this, SIGNAL(initDetector()), d, SLOT(initDetector()));
    connect(this, SIGNAL(freeDetector()), d, SLOT(freeDetector()));
    connect(t, SIGNAL(finished()), d, SLOT(deleteLater()));
    connect(d, SIGNAL(deviceStatus(DetectorState,QString)),
            this, SLOT(onDeviceStatus(DetectorState,QString)));
    d->moveToThread(t);
    t->start();
    emit initDetector();
}

bool DetectorWidget::getDetectorConfig(DetectorConfig &config) const
{
    QString cfg = QCoreApplication::applicationDirPath() + "/"PLUGIN_DETECTOR_CONFIG;
    if (QFile::exists(cfg)) {
        QSettings s(cfg, QSettings::IniFormat);
        s.setIniCodec(QSETTINGS_CODEC_NAME);
        config.name = s.value(DETECTOR_GENERAL_NAME).toString();
        config.type = s.value(DETECTOR_GENERAL_TYPE).toString();
        config.id = s.value(DETECTOR_GENERAL_ID).toString();
        config.acqLib = s.value(DETECTOR_GENERAL_ACQLIB).toString();
        config.specifics.modality = s.value(DETECTOR_SPECIFICS_MODALITY).toString();
        config.specifics.imageType = s.value(DETECTOR_SPECIFICS_IMAGETYPE).toString();
        config.specifics.conversionType = s.value(DETECTOR_SPECIFICS_CONVERSIONTYPE).toString();
        config.specifics.pixelWidth = s.value(DETECTOR_SPECIFICS_PIXELWIDTH).toFloat();
        config.specifics.pixelHeight = s.value(DETECTOR_SPECIFICS_PIXELHEIGHT).toFloat();
        config.specifics.bitsAllocated = s.value(DETECTOR_SPECIFICS_BITSALLOCATED).toInt();
        config.specifics.bitsStored = s.value(DETECTOR_SPECIFICS_BITSSTORED).toInt();
        config.specifics.highBit = s.value(DETECTOR_SPECIFICS_HIGHBIT).toInt();
        config.specifics.samplesPerPixel = s.value(DETECTOR_SPECIFICS_SAMPLESPERPIXEL).toInt();
        config.specifics.pixelRepresentation = s.value(DETECTOR_SPECIFICS_PIXELREPRESENTATION).toInt();
        config.specifics.rescaleIntercept = s.value(DETECTOR_SPECIFICS_RESCALEINTERCEPT).toInt();
        config.specifics.rescaleSlope = s.value(DETECTOR_SPECIFICS_RESCALESLOPE).toFloat();
        config.specifics.rescaleType = s.value(DETECTOR_SPECIFICS_RESCALETYPE).toString();
        config.specifics.interpret = s.value(DETECTOR_SPECIFICS_PHOTOMETRICINTERPRETATION).toString();
        config.specifics.explanation = s.value(DETECTOR_SPECIFICS_WINDOWCENTERWIDTHEXPLANATION).toString();
        config.specifics.processUid = s.value(DETECTOR_SPECIFICS_CLASSUIDFORPROCESSING).toString();
        config.specifics.presentUid = s.value(DETECTOR_SPECIFICS_CLASSUIDFORPRESENTATION).toString();
        config.transform.rotLeft = s.value(DETECTOR_TRANSFORM_ROTATELEFT).toBool();
        config.transform.rotRight = s.value(DETECTOR_TRANSFORM_ROTATERIGHT).toBool();
        config.transform.flipHori = s.value(DETECTOR_TRANSFORM_FLIPHORIZONTAL).toBool();
        config.transform.flipVert = s.value(DETECTOR_TRANSFORM_FLIPVERTICAL).toBool();
        return true;
    }
    return false;
}

ushort* DetectorWidget::getImage(ushort *&img, int &width, int &height)
{
    d->getImage(img, width, height);
    ui->acqBtn->setChecked(false);
    return img;
}

void DetectorWidget::startCapture(bool start)
{
    ui->acqBtn->setChecked(start);
}

void DetectorWidget::onDeviceStatus(DetectorState state, const QString &msg)
{
    QString detMsg;
    switch (state) {
    case DetInitializing:
        detMsg += tr("Detector initialing. ");
        break;
    case DetInited:
        detMsg += tr("Detector initialized. ");
        break;
    case DetInitFailed:
        detMsg += tr("Detector initilize failed. ");
        break;
    case DetCaptureStarting:
        detMsg += tr("Capture starting. ");
        break;
    case DetCaptureStarted:
        detMsg += tr("Capture started. ");
        break;
    case DetExposureReady:
        detMsg += tr("Ready, Expourse now. ");
        ui->exposureLabel->setPixmap(QPixmap(":/png/exp_green.png"));
        break;
    case DetCaptureFailed:
        detMsg += tr("Capture failed. ");
        ui->acqBtn->setChecked(false);
        break;
    case DetCaptureStartFailed:
        detMsg += tr("Capture start failed: ");
        ui->acqBtn->setChecked(false);
        break;
    case DetCaptureAborting:
        detMsg += tr("Capture aborting. ");
        break;
    case DetCaptureAborted:
        detMsg += tr("Capture aborted. ");
        ui->exposureLabel->setPixmap(QPixmap(":/png/exp_disable.png"));
        break;
    case DetCaptureAbortFailed:
        detMsg += tr("Capture abort failed: ");
        ui->acqBtn->setChecked(true);
        break;
    case DetImageReady:
        detMsg += tr("Image captured. ");
        if (m_proc) {
            QJsonObject json;
            json["action"] = "GetImage";
            m_proc(json, m_userData);
        }
        break;
    case DetFreeing:
        detMsg += tr("Detector freeing. ");
        break;
    case DetFreed:
        detMsg += tr("Detector freed. ");
        break;
    case DetFreeFailed:
        detMsg += tr("Detector free failed: ");
        break;
    case DetDisconnected:
        detMsg += tr("Detector disconnected: ");
        ui->acqBtn->setChecked(false);
        break;
    case DetTemperature:
        break;
    case DetError:
        break;
    }

    if (m_proc) {
        QJsonObject json;
        json["action"] = "ShowMessage";
        json["args"] = (detMsg + msg);
        m_proc(json, m_userData);
    }
}

void DetectorWidget::on_endBtn_clicked()
{
    if (m_proc) {
        QJsonObject json;
        json["action"] = "EndStudy";
        m_proc(json, m_userData);
    }
}
